package jinyilw.tools.audio;
import javax.sound.midi.MetaEventListener;
import javax.sound.midi.MetaMessage;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.Synthesizer;
import java.net.URL;

public class MidiRenderer extends BaseAudioRenderer implements MetaEventListener
{
	private static final int MIDI_EOT_MESSAGE = 47;
	private static final int GAIN_CONTROLLER = 7;
	private Sequencer sequencer;
	private static boolean available;
	private static boolean volumeSupported;
	private static final int UNINITIALIZED = 0;
	private static final int INITIALIZING = 1;
	private static final int INITIALIZED = 2;
	private static int rendererStatus = 0;

	public MidiRenderer()
	{
		if (rendererStatus == 0)
		{
			rendererStatus = 1;
			Thread thread = new Thread(() -> {
				try
				{
					Sequencer sequencer = MidiSystem.getSequencer();
					sequencer.open();
					MidiRenderer.volumeSupported = sequencer instanceof Synthesizer;
					sequencer.close();
					MidiRenderer.available = true;
				} catch (Throwable var2)
				{
					System.err.println("WARNING: Midi audio playback is not available!");
					MidiRenderer.available = false;
				}

				MidiRenderer.rendererStatus = 2;
			});
			thread.setDaemon(true);
			thread.start();
		}

	}

	public boolean isAvailable()
	{
		if (rendererStatus != 2)
		{
			int i = 0;

			while (rendererStatus != 2 && i++ < 50)
			{
				try
				{
					Thread.sleep(50L);
				} catch (InterruptedException ignored)
				{
				}
			}

			if (rendererStatus != 2)
			{
				rendererStatus = 2;
				available = false;
			}
		}

		return available;
	}

	protected void playSound(URL audioFile)
	{
		try
		{
			if (this.sequencer == null)
			{
				this.sequencer = MidiSystem.getSequencer();
				if (!this.sequencer.isOpen())
				{
					this.sequencer.open();
				}
			}

			Sequence seq = MidiSystem.getSequence(this.getAudioFile());
			this.sequencer.setSequence(seq);
			this.sequencer.start();
			this.sequencer.addMetaEventListener(this);
			if (this.volume != 1.0F)
			{
				this.setSoundVolume(this.volume);
			}
		} catch (Exception var3)
		{
			var3.printStackTrace();
			this.status = 4;
		}

	}

	protected void replaySound(URL audioFile)
	{
		this.sequencer.start();
		this.sequencer.addMetaEventListener(this);
	}

	protected void stopSound()
	{
		this.sequencer.stop();
		this.sequencer.setMicrosecondPosition(0L);
		this.sequencer.removeMetaEventListener(this);
	}

	public void meta(MetaMessage msg)
	{
		if (msg.getType() == 47)
		{
			this.status = 3;
			this.sequencer.setMicrosecondPosition(0L);
			this.sequencer.removeMetaEventListener(this);
		}

	}

	protected void setSoundVolume(float volume)
	{
		if (this.sequencer != null)
		{
			MidiChannel[] channels = ((Synthesizer) this.sequencer).getChannels();

			for (MidiChannel channel : channels)
			{
				channel.controlChange(7, (int) (volume * 127.0F));
			}

		}
	}

	public boolean isVolumeSupported()
	{
		return volumeSupported;
	}
}